# !/usr/bin python3
# -*- coding: utf-8 -*-

import time
import pytest
import os
import sys
sys.path.append(os.path.abspath(os.path.dirname(__file__)))
from common.ReadYaml import ReadYaml
from common.logger import GetLogger
from projectbusinessflows.base_api import BaseApi
from projectbusinessflows.user.LoginUtils import LoginApi
from common.tools import get_path
import pickle
from typing import (
    Any, List
)


@pytest.fixture(scope='session',autouse=True)
def 登录获取cookie():
    user = "admin"
    if os.path.exists(get_path(f'.auth/{user}_auth.json')) and int(
            time.time() - os.path.getmtime(get_path(f'.auth/{user}_auth.json'))) < 86400:
        # 文件存在了且创建时间小于1d，直接取出文件里面的cookie
        print(f"{user}对应的鉴权文件存在且创建时间小于1d，直接取文件cookie")
        with open(get_path(f'.auth/{user}_auth.json'), "rb") as f:
            # 要读取该文件并反序列化其中的内容，需要以二进制读取模式（"rb"）打开文件，并且使用 pickle.load 方法来进行反序列化操作
            cookies = pickle.load(f)
            # 因为token是键值对的形式，需要取一下
            cookie_str = "; ".join([f"{name}={value}" for name, value in cookies.items()])
            BaseApi.cookie = cookie_str
    else:
        print(f"{user}对应的token的json文件不存在或超过1d，调用登录接口")
        # 调用登录方法，拿到cookie，每个系统的鉴权字段名不一样，自行修改
        res = LoginApi(user).send()
        cookies = res.cookies
        print(f"写入{user}对应鉴权的json文件{cookies}")
        # 拿到cookie后，开始生成鉴权文件，并写入cookie
        with open(get_path(f'.auth/{user}_auth.json'), "wb") as f:
            # pickle 是 Python 中的一个用于序列化和反序列化对象的模块。序列化就是将一个 Python 对象转换为字节流的过程，以便可以将其存储到文件中、通过网络传输等。
            pickle.dump(cookies, f)
        cookie_str = "; ".join([f"{name}={value}" for name, value in cookies.items()])
        BaseApi.cookie = cookie_str


# def pytest_collection_modifyitems(config:"Config",items:List["Item"]):
#     # items对象是pytest收集到的所有用例对象
#     # 获取pytest.ini中的addopts值
#     try:
#         addopts = config.getini('addopts')
#         if "--dist=each" in addopts:
#             # 此时说明你要用的是多进程并发，我要得到当前的worker_id
#             worker_id = config.workerinput.get('workerid')
#         else:
#             worker_id = None
#     except:
#         worker_id = None
#     for item in items:
#         # item就代表了一条用例
#         if worker_id:
#             item.originalname = item.originalname.encode('utf-8').decode("unicode-escape")+worker_id
#             item._nodeid = item._nodeid.encode('utf-8').decode("unicode-escape")+worker_id
#         else:
#             item._nodeid = item._nodeid.encode('utf-8').decode("unicode-escape")

@pytest.fixture(scope='session',autouse=False)
def redis_init():
    redis_info = load_yaml_file(redis_yaml_path)
    r = RedisUtil(host=redis_info['host'], port=redis_info['port'], pwd=redis_info['password'])
    yield r

@pytest.fixture(scope='session',autouse=False)
def db_init():
    db_info = load_yaml_file(db_yaml_path)
    db_util = DBUtil(host=db_info['host'],user=db_info['username'],password=db_info['password'])
    yield db_util
    db_util.close()

def pytest_terminal_summary(terminalreporter, exitstatus, config):
    """统计测试结果"""
    passed = len(terminalreporter.stats.get('passed', []))
    failed = len(terminalreporter.stats.get('failed', []))
    error = len(terminalreporter.stats.get('error', []))
    skipped = len(terminalreporter.stats.get('skipped', []))
    total = passed+failed+error+skipped
    # terminalreporter._sessionstarttime 会话开始时间
    # duration = time.time() - terminalreporter._sessionstarttime
    print('total times:', 'seconds')
    ReadYaml('result.yml').write({"total":total,"passed":passed,"failed":failed,"skipped":skipped,"error":error})


@pytest.fixture(scope='session',autouse=True)
def logger_init(worker_id):
    GetLogger.get_logger(worker_id).info('日志初始化成功')

# @pytest.fixture(scope='session',autouse=False)
# def redis_init():
#     redis_info = load_yaml_file(redis_yaml_path)
#     r = RedisUtil(host=redis_info['host'], port=redis_info['port'], pwd=redis_info['password'])
#     yield r
#
# @pytest.fixture(scope='session',autouse=False)
# def db_init():
#     db_info = load_yaml_file(db_yaml_path)
#     db_util = DBUtil(host=db_info['host'],user=db_info['username'],password=db_info['password'])
#     yield db_util
#     db_util.close()



def pytest_addoption(parser: Any) -> None:
    """
    :param pytestconfig:
    :param parser:
    :return:
    action:表示要做的动作,如append(可以添加多个,返回列表),store(最常用,默认值,无则为store),store_true(调用就是true)
    nargs:指定个数,如nargs=2  nargs="*"表示多个
    type:返回的数据类型,默认为str
    """
    group = parser.getgroup("requests", "Requests")
    group.addoption(
        "--allure_report_auto_open",
        action="store",
        default="off",
        help="if finish test, allure report auto open, eg: /Users/liuyunlong/Desktop/pw-allure",
    )

# 测试执行结束后，自动打开allure测试报告
# @pytest.hookimpl(trylast=True)
# def pytest_sessionfinish(session):
#     allure_report_auto_open_config = session.config.getoption("--allure_report_auto_open")
#     if session.config.getoption("--allure_report_auto_open") != "off":
#         if sys.platform != "linux":
#             import subprocess
#             allure_report_dir = allure_report_auto_open_config
#             # 尝试关闭可能已经在运行的 Allure 服务
#             try:
#                 if sys.platform == 'darwin':  # macOS
#                     subprocess.call("pkill -f 'allure'", shell=True)
#                 elif sys.platform == 'win32':  # Windows
#                     command = "taskkill /F /IM java.exe /T"
#                     subprocess.call(command, shell=True, encoding="utf-8")
#             except Exception as e:
#                 print(e)
#             allure_command = f'allure serve {allure_report_dir}'
#             subprocess.Popen(allure_command, shell=True)